package com.riekoff.particlecubeworld.player;

import java.util.ArrayList;
import java.util.List;

import com.riekoff.particlecubeworld.editor.visual.AVisual;

import cc.creativecomputing.CCApp;
import cc.creativecomputing.graphics.CCDrawMode;
import cc.creativecomputing.graphics.CCGraphics;
import cc.creativecomputing.math.CCMath;
import cc.creativecomputing.math.CCVecMath;
import cc.creativecomputing.math.CCVector3f;
import cc.creativecomputing.math.util.CCArcball;

public class ABoxVisual implements AVisual{
	
	private CCApp _myApp;
	
	private CCArcball _myArcball;
	
	private class CCBox{
		private CCVector3f _myDimension;
		private CCVector3f _myPosition;
		
		public CCBox(CCVector3f theDimension, CCVector3f thePosition){
			_myDimension = theDimension;
			_myPosition = thePosition;
			_myPosition.x = CCMath.floor(thePosition.x / 10) * 10;
			_myPosition.y = CCMath.floor(thePosition.y / 10) * 10;
			_myPosition.z = CCMath.floor(thePosition.z / 10) * 10;
		}
		
		public void draw(CCGraphics g){
			g.pushMatrix();
			final float x1 = _myPosition.x - _myDimension.x / 2f;
			final float x2 = _myPosition.x + _myDimension.x / 2f;
			final float y1 = _myPosition.y - _myDimension.y / 2f;
			final float y2 = _myPosition.y + _myDimension.y / 2f;
			final float z1 = _myPosition.z - _myDimension.z / 2f;
			final float z2 = _myPosition.z + _myDimension.z / 2f;

			g.beginShape(CCDrawMode.QUADS);

			float u1,v1,u2,v2;
			u1 = (_myPosition.x + x1) / 1000 + 1;
			v1 = (_myPosition.y + y1) / 1000 + 1;
			u2 = (_myPosition.x + x2) / 1000 + 1;
			v2 = (_myPosition.y + y2) / 1000 + 1;
			
			// front
			g.normal(0,0,-1);
			g.textureCoords(0, u1,v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x1, y2, z1);
			
			g.textureCoords(0, u2, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x2, y2, z1);
			
			g.textureCoords(0, u2, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x2, y1, z1);
			
			g.textureCoords(0, u1, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x1, y1, z1);
			
			u1 = (_myPosition.z + z1) / 1000 + 1;
			v1 = (_myPosition.y + y1) / 1000 + 1;
			u2 = (_myPosition.z + z2) / 1000 + 1;
			v2 = (_myPosition.y + y2) / 1000 + 1;

			// right
			g.normal(1,0,0);
			g.textureCoords(0, u1, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x2, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x2, y2, z1);
			
			g.textureCoords(0, u2, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x2, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x2, y2, z2);
			
			g.textureCoords(0, u2, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x2, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x2, y1, z2);
			
			g.textureCoords(0, u1, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x2, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x2, y1, z1);
			
			u1 = (_myPosition.x + x1) / 1000 + 1;
			v1 = (_myPosition.y + y1) / 1000 + 1;
			u2 = (_myPosition.x + x2) / 1000 + 1;
			v2 = (_myPosition.y + y2) / 1000 + 1;

			// back
			g.normal(0,0,1);
			g.textureCoords(0, u2, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z2);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x2, y2, z2);
			
			g.textureCoords(0, u1, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z2);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x1, y2, z2);
			
			g.textureCoords(0, u1, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z2);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x1, y1, z2);
			
			g.textureCoords(0, u2, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z2);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 1, 2);
			g.vertex(x2, y1, z2);
			
			u1 = (_myPosition.z + z1) / 1000 + 1;
			v1 = (_myPosition.y + y1) / 1000 + 1;
			u2 = (_myPosition.z + z2) / 1000 + 1;
			v2 = (_myPosition.y + y2) / 1000 + 1;

			// left
			g.normal(-1,0,0);
			g.textureCoords(0, u2, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x1, y2, z2);
			
			g.textureCoords(0, u1, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x1, y2, z1);
			
			g.textureCoords(0, u1, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x1, y1, z1);
			
			g.textureCoords(0, u2, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 2, 1, 0);
			g.vertex(x1, y1, z2);
			
			u1 = (_myPosition.x + x1) / 1000 + 1;
			v1 = (_myPosition.z + z1) / 1000 + 1;
			u2 = (_myPosition.x + x2) / 1000 + 1;
			v2 = (_myPosition.z + z2) / 1000 + 1;

			// top
			g.normal(0,-1,0);
			g.textureCoords(0, u1, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x1, y1, z1);
			
			g.textureCoords(0, u2, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x2, y1, z1);
			
			g.textureCoords(0, u2, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x2, y1, z2);
			
			g.textureCoords(0, u1, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y1, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x1, y1, z2);
			
			u1 = (_myPosition.x + x1) / 1000 + 1;
			v1 = (_myPosition.z + z1) / 1000 + 1;
			u2 = (_myPosition.x + x2) / 1000 + 1;
			v2 = (_myPosition.z + z2) / 1000 + 1;

			// bottom
			g.normal(0,1,0);
			g.textureCoords(0, u1, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y2, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x1, y2, z2);
			
			g.textureCoords(0, u2, v2);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y2, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x2, y2, z2);
			
			g.textureCoords(0, u2, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y2, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x2, y2, z1);
			
			g.textureCoords(0, u1, v1);
			g.textureCoords(1, u1,v1, u2, v2);
			g.textureCoords(2, x1, y2, z1);
			g.textureCoords(3, x2, y2, z2);
			g.textureCoords(4, 0, 2, 1);
			g.vertex(x1, y2, z1);

			g.endShape();
			g.popMatrix();
		}
	}
	
	private List<CCBox> _myBoxes = new ArrayList<>();
	
	public ABoxVisual(CCApp theApp){
		_myApp = theApp;
		
		_myArcball = new CCArcball(theApp);
		
		for(int i = 0; i < 50;i++){
			CCVector3f myDimension = new CCVector3f(
				CCMath.floor(CCMath.random(20,200) / 20) * 20,
				CCMath.floor(CCMath.random(20,200) / 20) * 20,
				CCMath.floor(CCMath.random(20,200) / 20) * 20
			);
			_myBoxes.add(new CCBox(myDimension, CCVecMath.random3f(CCMath.random(500))));
		}
	}
	
	

	@Override
	public void draw(CCGraphics g) {
		g.pushMatrix();
		_myArcball.draw(g);
		
		for(CCBox myBox:_myBoxes){
			myBox.draw(g);
		}
		g.popMatrix();
	}

}
